# -*- coding: utf-8 -*-
import atexit
import sys
import ssl

from pyVim.connect import Disconnect, SmartConnect
from pyVmomi import vim

vcenter_ip = "172.16.100.57"
vcenter_port = "443"
vcenter_user = "administrator@vsphere.local"
vcenter_pwd = "Shsnc123!@#"
# 分配信息
esxi_host = "172.16.100.50"
create_cpu_cores = 2
create_memory_sizeGB = 4
create_store_sizeGB = 500


class vCenterManager():
    def __init__(self, vcenter_ip, vcenter_port, vcenter_user, vcenter_pwd):
        self.vcenter_ip = vcenter_ip
        self.vcenter_port = vcenter_port
        self.vcenter_user = vcenter_user
        self.vcenter_pwd = vcenter_pwd
        self.context = None
        self.si = None
        # 建立与vSphere的连接
        if hasattr(ssl, '_create_unverified_context'):
            self.context = ssl._create_unverified_context()
        self.si = SmartConnect(host=self.vcenter_ip, port=self.vcenter_port, user=self.vcenter_user,
                               pwd=self.vcenter_pwd,
                               sslContext=self.context)
        if self.si is None:
            print("请检查vc账号密码")
            sys.exit(1)

        atexit.register(Disconnect, self.si)

    def get_vcenter_info(self):
        # 总存储容量
        datastore_capacity = 0
        # 总存储剩余
        datastore_free = 0
        # 主机信息列表
        host_info_list = []
        store_info_list = []
        # 异常宿主机
        host_error_list = []

        content = self.si.RetrieveContent()
        # 查询数据中心
        # for datacenter in content.rootFolder.childEntity:
        #    # 数据中心名称
        #    dc_name = datacenter.name

        # 获取所有宿主机对象
        host_view = content.viewManager.CreateContainerView(content.rootFolder, [vim.HostSystem], True)
        hosts = host_view.view
        host_view.Destroy()
        for host in hosts:
            # 获取宿主机的硬件信息
            hardware = host.hardware
            # 获取宿主机状态
            connection_state = host.runtime.connectionState
            power_state = host.runtime.powerState
            # 是否是维护模式
            in_maintenance_mode = host.runtime.inMaintenanceMode
            if connection_state == 'connected' and power_state == 'poweredOn' and not in_maintenance_mode:
                # 获取 CPU 信息
                cpu_info = hardware.cpuInfo
                cpu_capacity = cpu_info.numCpuCores * cpu_info.hz / 1e9
                cpu_usage = host.summary.quickStats.overallCpuUsage / 1000.0
                cpu_available = cpu_capacity - cpu_usage
                # 获取 内存 信息
                memory_capacity = hardware.memorySize / (1024 ** 3)  # 将字节转换为 GB
                memory_usage = host.summary.quickStats.overallMemoryUsage / 1024.0  # GB
                memory_available = memory_capacity - memory_usage

                # 输出
                host_info_dict = {
                    "hostname": host.name,  # 宿主机名称
                    #"cpu_ghz": cpu_info.hz / 1000000,  # GHZ
                    # "cpu_package": cpu_info.numCpuPackages,  # CPU插槽
                    # "cpu_core": cpu_info.numCpuCores,  # cpu核心
                    # "cpu_thread": cpu_info.numCpuThreads,  # cpu线程
                    "cpu_total": cpu_info.numCpuCores * cpu_info.numCpuCores * cpu_info.numCpuThreads,  # 总核心数
                    # "cpu_capacity": cpu_capacity,  # GHz
                    # "cpu_usage": cpu_usage,
                    "cpu_available": cpu_available,
                    "memory_capacity": memory_capacity,
                    # "memory_usage": memory_usage,
                    "memory_available": memory_available
                }
                # 加入主机列表
                host_info_list.append(host_info_dict)
                print(
                    f"宿主机{host.name}: 总CPU={host_info_dict['cpu_total']:.2f}GHz, 可用CPU={host_info_dict['cpu_available']:.2f}GHz, 总内存={host_info_dict['memory_capacity']:.2f}GB, 可用内存={host_info_dict['memory_available']:.2f}GB")
                # 遍历所有数据存储
                for datastore in host.datastore:
                    store_capacity = datastore.summary.capacity
                    store_free = datastore.summary.freeSpace
                    store_usage = store_capacity - store_free
                    store_info_dict = {
                        "store_name": host.name,
                        "store_capacity": store_capacity / (1024 ** 4),
                        "store_free": store_free / (1024 ** 4),
                        "store_used": store_usage / (1024 ** 4)
                    }
                    # 加入存储列表
                    store_info_list.append(store_info_dict)
                    # 总存储量
                    datastore_capacity += store_capacity
                    datastore_free += store_free
            else:
                print("{}宿主机异常,加入异常列表".format(host.name))
                host_error_list.append(host.name)

        # 总存储使用
        datastore_used = datastore_capacity - datastore_free
        datastore_info_dict = {
            "datastore_capacity": datastore_capacity / (1024 ** 4),  # TB
            "datastore_free": datastore_free / (1024 ** 3),  # GB
            "datastore_used": datastore_used / (1024 ** 3),  # GB
        }

        print(
            f"数据中心总存储: {datastore_info_dict['datastore_capacity']:.2f}TB, 可用存储: {datastore_info_dict['datastore_free']:.2f}GB")
        # 返回主机信息、本地存储信息、总存储、异常宿主机
        return host_info_list, store_info_list, datastore_info_dict, host_error_list


def resource_check(vcinfo):
    # 判断主机信息和存储
    vcinfo_host = vcinfo[0]
    # vcinfo_store=vcinfo[1]
    vcinfo_datastore = vcinfo[2]

    # 判断主机资源
    for host in vcinfo_host:
        if host["hostname"] == esxi_host:
            if create_cpu_cores < host["cpu_available"] and create_memory_sizeGB < host[
                "memory_available"] and create_store_sizeGB < vcinfo_datastore["datastore_free"]:
                print(
                    f"当前{esxi_host}剩余：{host['cpu_available']:.2f}核CPU，{host['memory_available']:.2f}GB内存，{vcinfo_datastore['datastore_free']:.2f}GB存储")
                print("ESXI资源满足虚机创建所需资源，虚机创建可继续")
            else:
                print("资源不足")


if __name__ == '__main__':
    vc = vCenterManager(vcenter_ip, vcenter_port, vcenter_user, vcenter_pwd)
    # 返回vc资源
    vcinfo = vc.get_vcenter_info()
    host_info_list = vcinfo[0]
    # store_info_list=vcinfo[1]
    datastore_info_dict = vcinfo[2]
    host_error_list = vcinfo[3]
    # print(host_info_list)
    # # print(store_info_list)
    # print(datastore_info_dict)
    # print(host_error_list)
    # # print(vcinfo)
    # # resource_check(vcinfo)
